var express = require('express')
var router = express.Router()
const sequelize = require('../libs/db')
const Op = require('sequelize').Op
const User = require('../models/user')(sequelize)
const Role = require('../models/role')(sequelize)
const Tool = require('../libs/tool')
const { check, validationResult } = require('express-validator/check')
const Interceptor = require('../libs/interceptor')
const jwt = require('jsonwebtoken')
const config = require('../config/config')

/* GET users listing. */
router.get('/', async function(req, res, next) {
  const whereObj = {}
  const userNow = req.decoded
  if (req.query.key) {
    whereObj['user_name'] = {
      [Op.like]: '%' + req.query.key + '%'
    }
  }
  if (req.query.userName) {
    whereObj['user_name'] = {
      [Op.like]: '%' + req.query.userName + '%'
    }
  }
  const orderObj = []
  if (req.query.order && req.query.sortby) {
    if (req.query.sortby === 'roleName') {
      req.query.sortby = 'roleId'
    }
    orderObj.push([req.query.sortby, req.query.order])
  }
  const interceptor = new Interceptor(req)
  const { offset = 1, limit = 10 } = interceptor.page()
  const result = await User.findAndCountAll({
    include: [
      {
        attributes: [['role_name', 'roleName']],
        association: User.belongsTo(Role, { foreignKey: 'role_id' })
      }
    ],
    raw: true,
    where: whereObj,
    order: orderObj,
    offset: offset,
    limit: limit
  })
  for (let idata = 0; idata < result.rows.length; idata++) {
    result.rows[idata].isActiveName =
      result.rows[idata].isActive === 1 ? '是' : result.rows[idata].isActive === 0 ? '否' : ''
    if (result.rows[idata].id === 1) {
      result.rows[idata].isAdminName = '系统管理员'
    } else {
      result.rows[idata].isAdminName =
        result.rows[idata].isAdmin === 1 ? '管理员' : result.rows[idata].isAdmin === 0 ? '普通用户' : ''
    }
    result.rows[idata].roleName = result.rows[idata]['roleModel.roleName']
  }
  return res.json({
    code: 0,
    msg: '',
    items: result.rows,
    total: result.count
  })
})

router.get('/menus', async function(req, res, next) {
  const roles = await Role.findAll({
    raw: true
  })
  return res.json({
    code: 0,
    msg: '',
    roles: roles
  })
})

const dbValidator = [
  check('userName')
    .not()
    .isEmpty()
    .withMessage('用户名不能为空'),
  check('loginName')
    .not()
    .isEmpty()
    .withMessage('用户登录名不能为空')
]
const createValidator = Object.assign([], dbValidator)
createValidator.push(
  check('passwd')
    .not()
    .isEmpty()
    .withMessage('用户登录密码不能为空')
)
router.post('/', createValidator, async function(req, res) {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    const errObj = Tool.validatorError(errors)
    return res.status(errObj.code).json(errObj)
  }

  try {
    const user = await User.create({
      userName: req.body.userName,
      loginName: req.body.loginName,
      passwd: Tool.encrypt(req.body.passwd),
      email: req.body.email ? req.body.email : null,
      mobile: req.body.mobile ? req.body.mobile : null,
      roleId: req.body.roleId,
      isActive: req.body.isActive,
      isAdmin: req.body.isAdmin,
      shareCode: Tool.randomStr(16)
    })
    return res.json({
      code: 0,
      msg: '',
      user: user
    })
  } catch (err) {
    console.log(err)
    const exceptionObj = Tool.exceptionError(err)
    return res.status(exceptionObj.code).json(exceptionObj)
  }
})

const updateValidator = Object.assign([], dbValidator)
updateValidator.push(
  check('id')
    .not()
    .isEmpty()
    .withMessage('用户ID不能为空')
)
router.put('/:id(\\d+)', updateValidator, async function(req, res) {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    const errObj = Tool.validatorError(errors)
    return res.status(errObj.code).json(errObj)
  }
  // 从req.params中获取，还是字符型
  if (req.params.id === '1' && (req.body.isActive === '0' || req.body.isAdmin === '0')) {
    return res.status(500).json({
      code: 500,
      msg: '超级管理员的【激活】和【管理员】属性不能被修改成【否】状态'
    })
  }
  const user = await User.findByPk(req.params.id)
  if (!user) {
    return res.status(404).json({
      code: 404,
      msg: '未找到该数据'
    })
  }

  try {
    const updateData = {
      userName: req.body.userName,
      loginName: req.body.loginName,
      email: req.body.email ? req.body.email : null,
      mobile: req.body.mobile ? req.body.mobile : null,
      roleId: req.body.roleId,
      isActive: req.body.isActive,
      isAdmin: req.body.isAdmin
    }
    if (req.body.passwd) {
      updateData.passwd = Tool.encrypt(req.body.passwd)
    }
    const affectedRows = await User.update(updateData, {
      where: {
        userId: req.params.id
      }
    })
    return res.json({
      code: 0,
      msg: '',
      affectedRows: affectedRows[0]
    })
  } catch (err) {
    const exceptionObj = Tool.exceptionError(err)
    return res.status(exceptionObj.code).json(exceptionObj)
  }
})

const deleteValidator = [
  check('ids')
    .not()
    .isEmpty()
    .withMessage('用户ID不能为空')
]
router.delete('/:ids', deleteValidator, async function(req, res) {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    const errObj = Tool.validatorError(errors)
    return res.status(errObj.code).json(errObj)
  }
  const ids = req.params.ids.split(',')
  const deleteCount = await User.count({
    where: {
      userId: {
        [Op.in]: ids
      }
    }
  })
  if (deleteCount !== ids.length) {
    return res.status(404).json({
      code: 404,
      msg: '未找到匹配的数据'
    })
  }
  // ID为1的作为系统的超级管理员
  if (ids.indexOf('1') !== -1) {
    return res.status(500).json({
      code: 500,
      msg: '不能删除系统管理员'
    })
  }
  try {
    const destroyedRows = await User.destroy({
      where: {
        userId: {
          [Op.in]: ids
        }
      }
    })
    return res.json({
      code: 0,
      msg: '',
      destroyedRows: destroyedRows
    })
  } catch (err) {
    const exceptionObj = Tool.exceptionError(err)
    return res.status(exceptionObj.code).json(exceptionObj)
  }
})

const loginValidator = [
  check('loginName')
    .not()
    .isEmpty()
    .withMessage('用户登录名不能为空'),
  check('passwd')
    .not()
    .isEmpty()
    .withMessage('用户登录密码不能为空')
]
// 用户授权路径，返回JWT 的 Token 验证用户名密码
router.post('/login', loginValidator, async function(req, res) {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    const errObj = Tool.validatorError(errors)
    return res.status(errObj.code).json(errObj)
  }
  let user = await User.findOne({
    where: {
      loginName: req.body.loginName
    }
  })
  if (!user) {
    return res.status(404).json({
      code: 404,
      msg: '用户名或者密码错误'
    })
  } else if (user) {
    user = user.get({
      plain: true
    })
    if (user.passwd !== Tool.encrypt(req.body.passwd)) {
      return res.status(401).json({
        code: 401,
        msg: '用户名或者密码错误'
      })
    } else if (user.isActive === 0) {
      return res.status(401).json({
        code: 401,
        msg: '用户未激活'
      })
    } else {
      const role = await Role.findByPk(user.roleId)
      if ((role && role.permission.split(',').length > 0) || user.userId === 1) {
        let permissionList = role ? role.permission.split(',') : []
        // 对象的属性，此时是整形
        if (user.userId === 1) {
          permissionList = config.features.map(element => {
            return '/' + element.key
          })
        } else {
          // 不在features列表中的功能删除掉，避免找不到该功能，跳转到404页面
          var iPermission = permissionList.length
          while (iPermission--) {
            let flg = false
            config.features.some(feature => {
              if (feature.key === permissionList[iPermission]) {
                flg = true
                return true
              }
            })
            if (!flg) {
              permissionList.splice(iPermission, 1)
            }
          }
          permissionList = permissionList.map(element => {
            return '/' + element
          })
        }
        var token = jwt.sign({
          id: user.userId,
          companyId: user.companyId,
          loginName: user.loginName,
          userName: user.userName,
          permission: permissionList
        }, config.jwt.secret, {
          expiresIn: 60 * 60 * 24 // 授权时效24小时
        })

        const retUser = {
          loginName: user.loginName,
          userName: user.userName,
          avatar: user.avatar ? user.avatar : '',
          isSysAdmin: Tool.isSysAdmin(user),
          permission: permissionList,
          homePage: permissionList[0]
        }
        return res.json({
          code: 0,
          msg: '请使用用户令牌',
          user: retUser,
          token: token
        })
      } else {
        return res.status(401).json({
          code: 401,
          msg: '没有任何管理员权限'
        })
      }
    }
  }
})
// 获取当前用户的信息
router.get('/information', async function(req, res) {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    const errObj = Tool.validatorError(errors)
    return res.status(errObj.code).json(errObj)
  }
  const user = await User.findOne({
    raw: true,
    attributes: ['loginName', 'userName', 'email', 'mobile'],
    where: {
      userId: req.decoded.id
    }
  })
  if (!user) {
    return res.status(404).json({
      code: 404,
      msg: '未找到授权用户'
    })
  } else if (user) {
    return res.json({
      code: 0,
      user: user
    })
  }
})

router.put('/information', dbValidator, async function(req, res) {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    const errObj = Tool.validatorError(errors)
    return res.status(errObj.code).json(errObj)
  }
  const user = await User.findByPk(req.decoded.id)
  if (!user) {
    return res.status(404).json({
      code: 404,
      msg: '未找到该数据'
    })
  }
  try {
    const updateData = {
      userName: req.body.userName,
      email: req.body.email ? req.body.email : null,
      mobile: req.body.mobile ? req.body.mobile : null
    }
    const affectedRows = await User.update(updateData, {
      where: {
        userId: req.decoded.id
      }
    })
    return res.json({
      code: 0,
      msg: '',
      affectedRows: affectedRows[0]
    })
  } catch (err) {
    const exceptionObj = Tool.exceptionError(err)
    return res.status(exceptionObj.code).json(exceptionObj)
  }
})

router.put(
  '/password',
  [
    check('oldPassword')
      .not()
      .isEmpty()
      .withMessage('用户原登录密码不能为空'),
    check('newPassword')
      .not()
      .isEmpty()
      .withMessage('用户新登录密码不能为空'),
    check('confirmPassword')
      .not()
      .isEmpty()
      .withMessage('用户确认登录密码不能为空')
  ],
  async function(req, res) {
    const errors = validationResult(req)
    if (!errors.isEmpty()) {
      const errObj = Tool.validatorError(errors)
      return res.status(errObj.code).json(errObj)
    }
    const user = await User.findByPk(req.decoded.id)
    if (!user) {
      return res.status(404).json({
        code: 404,
        msg: '未找到该数据'
      })
    }
    if (user.passwd !== Tool.encrypt(req.body.oldPassword)) {
      return res.status(500).json({
        code: 500,
        msg: '用户原密码错误'
      })
    } else if (req.body.newPassword !== req.body.confirmPassword) {
      return res.status(500).json({
        code: 500,
        msg: '两次输入密码不一致'
      })
    }
    try {
      const updateData = {
        passwd: Tool.encrypt(req.body.newPassword)
      }
      const affectedRows = await User.update(updateData, {
        where: {
          userId: req.decoded.id
        }
      })
      return res.json({
        code: 0,
        msg: '',
        affectedRows: affectedRows[0]
      })
    } catch (err) {
      const exceptionObj = Tool.exceptionError(err)
      return res.status(exceptionObj.code).json(exceptionObj)
    }
  }
)

module.exports = router
